package cn.tangshh.universal.core.api;

import cn.hutool.core.map.MapUtil;
import cn.tangshh.universal.core.util.MessageUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.http.HttpStatus;

import java.util.Map;

/**
 * 基础返回数据
 *
 * @author Tang
 * @version v1.0
 * @since 2024/05/30
 */
@Data
@Schema(title = "基础返回数据")
@EqualsAndHashCode(callSuper = true)
public final class DR<T> extends R<T> {
    public static <T> DR<T> ok() {
        RCode success = RCode.SUCCESS;
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(success.getMessage()));
        dr.setCode(success);
        dr.setSuccess(true);
        return dr;
    }

    public static <T> DR<T> okMsg(String msg) {
        RCode success = RCode.SUCCESS;
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(msg));
        dr.setCode(success);
        dr.setSuccess(true);
        return dr;
    }

    public static <T> DR<T> ok(T data) {
        DR<T> ok = ok();
        ok.setData(data);
        return ok;
    }

    public static <T> DR<T> ok(T data, String msg) {
        RCode success = RCode.SUCCESS;
        DR<T> dr = new DR<>();
        dr.setData(data);
        dr.setMsg(MessageUtil.convert(msg));
        dr.setCode(success);
        dr.setSuccess(true);
        return dr;
    }

    public static <T> DR<T> fail() {
        RCode fail = RCode.BAD_REQUEST;
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(fail.getMessage()));
        dr.setCode(fail);
        dr.setSuccess(false);
        return dr;
    }


    public static <T> DR<T> fail(String msg) {
        RCode fail = RCode.BAD_REQUEST;
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(msg));
        dr.setCode(fail);
        dr.setSuccess(false);
        return dr;
    }


    public static <T> DR<T> of(Boolean result) {
        if (Boolean.TRUE.equals(result)) {
            return ok();
        }
        return fail();
    }

    public static <T> DR<T> of(RCode rCode) {
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(rCode.getMessage()));
        dr.setCode(rCode);
        dr.setSuccess(rCode.getCode() <= 300);
        return dr;
    }

    public static <T> DR<T> of(RCode code, String msg) {
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(msg));
        dr.setCode(code);
        dr.setSuccess(code.getCode() <= 300);
        return dr;
    }

    public static <T> DR<T> of(HttpStatus status) {
        DR<T> dr = new DR<>();
        dr.setMsg(status.getReasonPhrase());
        dr.setCode(RCode.of(status.value()));
        dr.setSuccess(status.is2xxSuccessful());
        return dr;
    }

    public static <T> R<T> of(Integer code, String msg) {
        DR<T> dr = new DR<>();
        dr.setMsg(MessageUtil.convert(msg));
        dr.setCode(RCode.of(code));
        dr.setSuccess(code <= 300);
        return dr;
    }

    public static DR<Map<String, Object>> okMap(String key, Object value) {
        DR<Map<String, Object>> okMap = ok();
        okMap.setData(MapUtil.of(key, value));
        return okMap;
    }

    @SuppressWarnings("unchecked")
    public void put(String key, Object value) {
        T data = getData();
        if (data instanceof Map) {
            ((Map<String, Object>) data).put(key, value);
        } else if (data == null) {
            setData((T) MapUtil.of(key, value));
        }
    }
}